package com.demo2;// ========== 1. 密钥生成器 - 独立程序 ==========
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.io.*;
import java.util.*;
import javax.crypto.Cipher;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;

/**
 * 独立的密钥生成器程序
 * 只需要运行一次，生成公私钥对
 */
public class KeyGenerator {
    private static final String ALGORITHM = "RSA";
    private static final int KEY_SIZE = 2048;

    public static void main(String[] args) {
        try {
            System.out.println("=== License系统密钥生成器 ===");

            KeyGenerator generator = new KeyGenerator();
            generator.generateAndSaveKeys();

            System.out.println("密钥生成完成！");
            System.out.println("请妥善保管private_key.pem文件，用于生成license");
//            System.out.println("public_key.pem文件将嵌入到客户端程序中");

        } catch (Exception e) {
            System.err.println("密钥生成失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public void generateAndSaveKeys() throws Exception {
        // 1. 生成密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
        keyGen.initialize(KEY_SIZE);
        KeyPair keyPair = keyGen.generateKeyPair();

        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        // 2. 保存私钥到文件
        savePrivateKey(privateKey, "private_key.pem");

        // 3. 保存公钥到文件
        savePublicKey(publicKey, "public_key.pem");

        // 4. 生成Java代码格式的公钥常量
//        generatePublicKeyJavaCode(publicKey, "PublicKeyConstant.java");

        // 5. 显示密钥信息
        displayKeyInfo(privateKey, publicKey);
    }

    private void savePrivateKey(PrivateKey privateKey, String filename) throws IOException {
        byte[] privateKeyBytes = privateKey.getEncoded();
        String privateKeyString = Base64.getEncoder().encodeToString(privateKeyBytes);

        try (FileWriter writer = new FileWriter(filename)) {
            writer.write("-----BEGIN PRIVATE KEY-----\n");
            // 每64个字符换行
            for (int i = 0; i < privateKeyString.length(); i += 64) {
                int end = Math.min(i + 64, privateKeyString.length());
                writer.write(privateKeyString.substring(i, end) + "\n");
            }
            writer.write("-----END PRIVATE KEY-----\n");
        }

        System.out.println("私钥已保存到: " + filename);
    }

    private void savePublicKey(PublicKey publicKey, String filename) throws IOException {
        byte[] publicKeyBytes = publicKey.getEncoded();
        String publicKeyString = Base64.getEncoder().encodeToString(publicKeyBytes);

        try (FileWriter writer = new FileWriter(filename)) {
            writer.write("-----BEGIN PUBLIC KEY-----\n");
            // 每64个字符换行
            for (int i = 0; i < publicKeyString.length(); i += 64) {
                int end = Math.min(i + 64, publicKeyString.length());
                writer.write(publicKeyString.substring(i, end) + "\n");
            }
            writer.write("-----END PUBLIC KEY-----\n");
        }

        System.out.println("公钥已保存到: " + filename);
    }

    private void generatePublicKeyJavaCode(PublicKey publicKey, String filename) throws IOException {
        byte[] publicKeyBytes = publicKey.getEncoded();
        String publicKeyString = Base64.getEncoder().encodeToString(publicKeyBytes);

        try (FileWriter writer = new FileWriter(filename)) {
            writer.write("// 自动生成的公钥常量类\n");
            writer.write("// 生成时间: " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "\n");
            writer.write("public class PublicKeyConstant {\n");
            writer.write("    // 将此常量复制到LicenseValidator类中\n");
            writer.write("    public static final String PUBLIC_KEY = \n");
            writer.write("        \"" + publicKeyString + "\";\n");
            writer.write("}\n");
        }

        System.out.println("Java公钥常量已保存到: " + filename);
    }

    private void displayKeyInfo(PrivateKey privateKey, PublicKey publicKey) {
        System.out.println("\n=== 密钥信息 ===");
        System.out.println("算法: " + privateKey.getAlgorithm());
        System.out.println("密钥长度: " + KEY_SIZE + " bits");
        System.out.println("私钥格式: " + privateKey.getFormat());
        System.out.println("公钥格式: " + publicKey.getFormat());
        System.out.println("生成时间: " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
    }
}



